home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Development Platforms / Apple II / Essentials / Technical.Notes / IIGS / TN.IIGS.090 < prev    next >
Encoding:
Text File  |  1991-06-28  |  6.0 KB  |  137 lines  |  [TEXT/pdos]

  1. Apple II
  2. Technical Notes
  3. _____________________________________________________________________________
  4.                                                   Developer Technical Support
  5.  
  6.  
  7. Apple IIgs
  8. #90:         65816 Tips and Pitfalls
  9.  
  10. Revised by:  Matt "Matt" Deatherage                                March 1991
  11. Written by:  Dave "Dave" Lyons                                 September 1990
  12.  
  13. This Technical Note presents short 65816 assembly language examples
  14. illustrating pitfalls and clever techniques.
  15.  
  16. Changes since November 1990:  Added more explanations about the JSL table and
  17. corrected a comment.
  18. _____________________________________________________________________________
  19.  
  20.  
  21.  
  22. Dispatching Through an Address Table
  23.  
  24. The 65816 has a JSR ($aaaa,X) instruction for calling a selected subroutine
  25. from a table of addresses, but it has no JSL ($aaaa,X) instruction.  If you
  26. need to dispatch to one of several routines that are not all in the same 
  27. bank,
  28. you need an approach like the following.  The idea is to perform a JSL to a
  29. routine which does a long jump by pushing a three-byte "RTL address" on the
  30. stack and then doing an RTL.
  31.  
  32.            jsl LngJmp           ;go jump to the routine
  33.            ...
  34.  
  35.   LngJmp   asl a                ;take routine number in A and
  36.            asl a                ; multiply it by 4
  37.            tax                  ;put table index into X
  38.            lda table+1,x        ;get "middle" word of address
  39.            pha                  ; and push it
  40.            lda table,x          ;get low word and
  41.            dec a                ; decrement it by one
  42.            phb                  ;push a single throw-away byte
  43.            sta 1,s              ;store over low two of the 3 bytes
  44.            rtl                  ;transfer control to the routine
  45. table      dc.l routine1        ;table of 4-byte subroutine addresses
  46.            dc.l routine2
  47.            dc.l routine3
  48.            ...
  49.  
  50. This code is correct because RTL pulls three bytes off the stack and 
  51. increments the two low bytes without incrementing the high byte.
  52.  
  53. Note:   This approach to a table-based JSL is more flexible than JML ($XXXX) 
  54.         because it does not require any fixed-location storage or bank zero 
  55.         space, other than the stack.
  56.  
  57.  
  58. On the other hand, the following code is not correct.  The approach here is 
  59. to make a table of addresses minus one.
  60.  
  61.            asl a             W
  62.            asl a             R  ;multiply index by 4
  63.            tax               O  ; and put it in X
  64.            lda table+1,x     N  ;get the "middle" word
  65.            pha               G  ; and push it
  66.            lda table,x       !  ;get the low word
  67.            phb               W  ;push a single throw-away byte
  68.            sta 1,s           R  ;store over low two bytes
  69.            rtl               O  ;transfer control to the routine
  70.     table  dc.l routine1-1   N  ;table of 4-byte addresses minus one
  71.            dc.l routine2-1   G
  72.            dc.l routine3-1   !
  73.            ...
  74. This second sample code fragment fails if any of the routines in the table
  75. comes at the first byte of a bank.  For example, if routine1 is at $060000, 
  76. the address pushed is $05FFFF, and RTL transfers control to $050000, not 
  77. $060000.
  78.  
  79. Dereferencing Handles Without Direct Page Space
  80.  
  81. When your code gets called with the D register undefined, you must not use
  82. direct page addressing without setting D to a known good value.  Preserving 
  83. and restoring locations on the caller's direct page is not reliable, because 
  84. D could be pointing at bytes below the stack pointer (which can be destroyed 
  85. by interrupts) or even at the $C0xx soft switches (that would make your 
  86. direct page accesses accidentally fiddle with hardware).
  87.  
  88. A common way to get temporary direct page space is to point D at part of your
  89. stack.  This following code dereferences a handle stored in the A and X
  90. registers (if the handle is $E01234 and refers to a block of memory at 
  91. $056789, then on entry A=$00E0 and X=$1234, and on exit A=$0005 and X=$6789).
  92.  
  93.        phd                  ;save caller's direct-page register
  94.        pha                  ;push high word of handle
  95.        phx                  ;push low word of handle
  96.        tsc                  ;get stack pointer in A
  97.        tcd                  ;and put it in D
  98.        lda [1]              ;get low word of master pointer (no ",Y"!)
  99.        tax                  ; and put it in X
  100.        ldy #$0002           ;offset to high word of master pointer
  101.        lda [1],y            ;get high word
  102.        ply                  ;remove low word of handle
  103.        ply                  ; and high word
  104.        pld                  ;restore the caller's direct-page register
  105.  
  106.  
  107. Direct page addressing isn't the only way to address through pointers.  
  108. Here's the same routine as before, but using the Data Bank register (B) 
  109. instead of fiddling with D.  (Note that handles do not have to be in bank $E0 
  110. or $E1, although they usually are.)
  111.  
  112.        phb                  ;save caller's data bank register
  113.        pha                  ;push high word of handle on stack
  114.        plb                  ;sets B to the bank byte of the pointer
  115.        lda |$0002,x         ;load the high word of the master pointer
  116.        pha                  ; and save it on the stack
  117.        lda |$0000,x         ;load the low word of the master pointer
  118.        tax                  ;and return it in X
  119.        pla                  ;restore the high word in A
  120.        plb                  ;pull the handle's high word high byte off the
  121.                             ; stack
  122.        plb                  ;restore the caller's data bank register
  123.  
  124. Emulation Mode Has 65816 Features
  125.  
  126. You don't have to switch into Native mode just to do an eight-bit operation
  127. with long addressing.  Most 65816-specific instructions and addressing modes
  128. work in emulation mode in approximately the same way they work in eight-bit
  129. native mode.  See the "Further Reference" for details.
  130.  
  131.  
  132. Further Reference
  133. _____________________________________________________________________________
  134.   o  Apple IIgs Hardware Reference
  135.   o  Programming the 65816, Including the 6502, 65C02 and 65802 (Eyes and
  136.      Lichty, 1986, Brady)
  137.